package gui.menu;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

import game.buildings.*;
import gui.*;
import main.Antiquity;

/**
 *	@(#)BuildingMenu.java
 *
 *	The <code>BuildingMenu</code> class represents the context menu
 *	for a building. It provides methods to buy, rotate and place the
 *	building.
 *
 *	@author Grzegorz Kobiela
 *	@version 1.1 2008/5/14
 */
public final class BuildingMenu
extends JPopupMenu
{
	/** A rotation to the left. */
	public static final int ROTATE_LEFT = -1;

	/** A rotation to the right. */
	public static final int ROTATE_RIGHT = 1;

	/** The overall rotation. */
	private int rotation = 0;

	/**
	 *	Adds the 'buy' option.
	 */
	public void addBuyOption() {
		JMenuItem item = new JMenuItem(Antiquity.get("cmPurchase"));
		add(item);
	}

	/**
	 *	Adds the 'place' option.
	 */
	public void addPlaceOption() {
		JMenuItem item = new JMenuItem(Antiquity.get("cmPlace"));
		add(item);
	}

	/**
	 *	Adds the 'back' option.
	 */
	public void addBackOption() {
		JMenuItem item = new JMenuItem(Antiquity.get("cmBack"));
		item.addActionListener(
			new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					DraggableLabel label = getLabel(e);
					if(rotation != 0) rotate(e, -rotation);
					((Building)label.getClientProperty("represents")).update(Antiquity.getCommand("Back"));
				}
			}
		);
		add(item);
	}

	/**
	 *	Adds the 'rotate' options.
	 */
	public void addRotateOptions() {
		JMenuItem item = new JMenuItem(Antiquity.get("cmRight"));
		item.addActionListener(
			new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					rotate(e, 1);
				}
			}
		);
		add(item);

		item = new JMenuItem(Antiquity.get("cmLeft"));
		item.addActionListener(
			new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					rotate(e, -1);
				}
			}
		);
		add(item);
	}

	/**
	 *	Returns the label which the given event has occured in.
	 *	@param e the event
	 *	@return the label
	 */
	private DraggableLabel getLabel(ActionEvent e) {
		return (DraggableLabel)((JPopupMenu)((JMenuItem)e.getSource()).getParent()).getInvoker();
	}

	/**
	 *	Rotates the label invoking the given event and its represented
	 *	building by the provided amount of steps.
	 *	@param e the event
	 *	@param n the amount of steps
	 */
	private void rotate(ActionEvent e, int n) {
		DraggableLabel label = getLabel(e);
		Building building = (Building)label.getClientProperty("represents");
		int angle = 90 * n;
		((Rotatable)building).rotate(n);
		rotation += n;
		ImageIcon icon;
		Rectangle bounds = label.getBounds();
		if(building instanceof Fisherman) {
			icon = GameUtilities.createIcon(building);
			label.setIcon(icon, Antiquity.getAlpha("Default"));
		} else {
			icon = ImageRotator.rotate((ImageIcon)label.getIcon(), angle);
			label.setIcon(icon);
			label.setOpaqueIcon(ImageRotator.rotate(label.getOpaqueIcon(), angle));
		}
		int x = label.getX() + label.getWidth() / 2;
		int y = label.getY() + label.getHeight() / 2;
		int w = icon.getIconWidth();
		int h = icon.getIconHeight();
		label.setBounds(x - w / 2, y - h / 2, w, h);
		label.setPolygon(GameUtilities.getOutline(building));
		Point location = label.getLocation();
		if(building instanceof Fisherman) {
			building.setLocation(game.LandSystem.getPoint(location));
		} else {
			label.rearrange(bounds, angle);
			building.update(game.CitySystem.getPoint(location));
		}
	}

	/**
	 *	Updates the menu options for a given city building.
	 *	@param bought provide true if the building is already bought
	 *	@return the instance
	 */
	public void updateCityMenu(boolean bought) {
		removeAll();
		if(!bought) {
			addBuyOption();
			addSeparator();
		}
		addRotateOptions();
		if(!bought) {
			addSeparator();
			addBackOption();
		}
	}

	/**
	 *	Updates the menu options for a given land building.
	 *	@param rotatable provide true if the building is rotatable
	 *	@return the instance
	 */
	public void updateLandMenu(boolean rotatable) {
		removeAll();
		addPlaceOption();
		if(rotatable) {
			addSeparator();
			addRotateOptions();
		}
	}
}